#include "Serial_port.h"
#include "main_windw.h"
#include "ui_main_windw.h"

#include <QtSerialPort/QSerialPort>    //串口相关文件
#include <QtSerialPort/QSerialPortInfo>
#include <QString>
#include <QDateTime>
#include <QTimer>
#include <windows.h>
#include <QIcon>
#include <QDebug>


/**
 * @brief MainWindow::Init_Port
 * 初始化串口设置
 */
#if 1
void Main_windw::Init_Port(void)
{

    QStringList BaudList;   //波特率
    QStringList ParityList; //校验位
    QStringList DataBitsList;   //数据位
    QStringList StopBitsList;   //停止位

    // 波特率    //波特率默认选择下拉第三项：9600
    BaudList<<"9600"<<"115200"<<"1200"<<"2400"<<"4800"<<"14400"<<"19200"<<"38400"<<"57600";
    // 校验      //校验默认选择无
    ParityList<<"无"<<"奇"<<"偶";
    // 数据位      //数据位默认选择8位
    DataBitsList<<"8"<<"5"<<"6"<<"7";
    // 停止位      //停止位默认选择1位
    StopBitsList<<"1"<<"2";

    SerialPort Serial(this); //临时变量添加端口号信息

    ui->port_number_Box->clear();
    ui->port_number_Box->addItems(Serial.Port_name);

    ui->baudrate_Box->clear();
    ui->baudrate_Box->addItems( BaudList);
    ui->baudrate_Box->setCurrentIndex(1);

    ui->stop_bit_Box->clear();
    ui->stop_bit_Box->addItems( StopBitsList);

    ui->data_bit_Box->clear();
    ui->data_bit_Box->addItems( DataBitsList);

    ui->parity_bit_Box->clear();
    ui->parity_bit_Box->addItems( ParityList);

    connect(this,&Main_windw::Port_event_signal,this,&Main_windw::Port_event_slot);

    qDebug()<<"Init port";
}
void Main_windw:: Port_event_slot(QString port_name,int state)
{
    qDebug()<<"Port_event_slot";
    if(state)
    {
         Refresh_com(port_name,state);
    }
    else
    {
         Refresh_com(port_name,state);
    }
}
void Main_windw::Serial_event_callback(SerialPort::E_EVENTS_T event,QStringList port_list)
{

    if(event == SerialPort::EVENT_PORT_DISCONNECT)
    {
        close_port();
        ui->port_number_Box->clear();
        ui->port_number_Box->addItems(port_list);
        qDebug()<<"EVENT_PORT_DISCONNECT";
        return;
    }
    if(event == SerialPort::EVENT_PORT_ADD_NEW)
    {

        ui->port_number_Box->clear();

        ui->port_number_Box->addItems(port_list);
        qDebug()<<"EVENT_PORT_ADD_NEW";
        return;
    }
    if(event == SerialPort::EVENT_PORT_REDUCE)
    {

        ui->port_number_Box->clear();

        ui->port_number_Box->addItems(port_list);
        qDebug()<<"EVENT_PORT_REDUCE";
        return;
    }
    if(event == SerialPort::EVENT_PORT_REFRESH)
    {

        ui->port_number_Box->clear();

        ui->port_number_Box->addItems(port_list);
        qDebug()<<"EVENT_PORT_REFRESH";
        return;
    }
}

void Main_windw::Refresh_com(QString port_name,int state)
{
    Q_UNUSED(state);
    const auto infos = QSerialPortInfo::availablePorts();


    QStringList New_port_name;
    New_port_name.clear();

    if(my_serial)
    {
        if(my_serial->isOpen() && (port_name.compare(my_serial->PortName) != 0))
        {
            New_port_name.append(my_serial->PortName);
        }
    }

    for(const QSerialPortInfo &info : infos)  //获取CMO口
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            //加载串口号
            New_port_name.append(info.portName());
            serial.close();
        }
    }

    /*新的列表不包含当前端口号,代表拔出设备*/

    if(my_serial)
    {
        if(my_serial->isOpen())
        {
            if(New_port_name.contains(my_serial->PortName) == false)
            {
                //发送信号
                Serial_event_callback(SerialPort::EVENT_PORT_DISCONNECT,New_port_name);
            }
            else
            {
                Serial_event_callback(SerialPort::EVENT_PORT_REFRESH,New_port_name);
            }
        }

    }
    else
    {
        Serial_event_callback(SerialPort::EVENT_PORT_REFRESH,New_port_name);
    }

}
#if 1
/**
 * @brief 重写的系统系统信息函数
*/
bool Main_windw::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(eventType);
    Q_UNUSED(result);
    MSG* msg = reinterpret_cast<MSG*>(message);//第一层解算
    UINT msgType = msg->message;
    if(msgType==WM_DEVICECHANGE)
    {
        //emit change_port();
        PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam);//第二层解算
        switch (msg->wParam) {
        case DBT_DEVICEARRIVAL:
            if(lpdb->dbch_devicetype == DBT_DEVTYP_PORT)
            {
                PDEV_BROADCAST_PORT  pDevInf  = PDEV_BROADCAST_PORT(lpdb);
                // QString device_name = "插入设备(name)："+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
                QString port = QString::fromWCharArray(pDevInf->dbcp_name);
                qDebug()<<"插入"+ port;

                emit Port_event_signal(port,1);

            }
            break;
        case DBT_DEVICEREMOVECOMPLETE:
            if(lpdb->dbch_devicetype == DBT_DEVTYP_PORT)
            {
                PDEV_BROADCAST_PORT  pDevInf  = PDEV_BROADCAST_PORT (lpdb);
                // QString device_name = "移除设备(name)："+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
                QString port = QString::fromWCharArray(pDevInf->dbcp_name);
                qDebug()<< "移除"+port;

                emit Port_event_signal(port,0);

            }
            break;
        }
    }
    return false;
}
/**
 * @brief 注册串口插入信息回调
 * main.c中show()后面添加 a.installNativeEventFilter(&w);
*/
void Main_windw::register_com_state_msg(void){
    static const GUID GUID_DEVINTERFACE_LIST[] =
        {
        // GUID_DEVINTERFACE_USB_DEVICE
        { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } },
    //    // GUID_DEVINTERFACE_DISK
    //    { 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } },
    //    // GUID_DEVINTERFACE_HID,
    //    { 0x4D1E55B2, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } },
    //    // GUID_NDIS_LAN_CLASS
    //    { 0xad498944, 0x762f, 0x11d0, { 0x8d, 0xcb, 0x00, 0xc0, 0x4f, 0xc3, 0x35, 0x8c } },
    //    // GUID_DEVINTERFACE_COMPORT
    //    { 0x86e0d1e0, 0x8089, 0x11d0, { 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73 } },
    //    // GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
    //    { 0x4D36E978, 0xE325, 0x11CE, { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } },
    //    // GUID_DEVINTERFACE_PARALLEL
    //    { 0x97F76EF0, 0xF883, 0x11D0, { 0xAF, 0x1F, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x5C } },
    //    // GUID_DEVINTERFACE_PARCLASS
    //    { 0x811FC6A5, 0xF728, 0x11D0, { 0xA5, 0x37, 0x00, 0x00, 0xF8, 0x75, 0x3E, 0xD1 } },
        };

        //注册插拔事件
        HDEVNOTIFY hDevNotify;
        DEV_BROADCAST_DEVICEINTERFACE NotifacationFiler;
        ZeroMemory(&NotifacationFiler,sizeof(DEV_BROADCAST_DEVICEINTERFACE));
        NotifacationFiler.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
        NotifacationFiler.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
        for(int i=0;i<int(sizeof(GUID_DEVINTERFACE_LIST)/sizeof(GUID));i++)
        {
            NotifacationFiler.dbcc_classguid = GUID_DEVINTERFACE_LIST[i];//GetCurrentUSBGUID();
            hDevNotify = RegisterDeviceNotification(HANDLE(this->winId()),&NotifacationFiler,DEVICE_NOTIFY_WINDOW_HANDLE);
            if(!hDevNotify)
            {
                GetLastError();
                qDebug() << "注册失败" <<endl;
            }
        }

}

#endif


void Main_windw::data_process(QByteArray data,qint16 len)
{
    //首先判断是否是处于查询状态
        static int mes_num = 0;
        if(!data.isEmpty()){  //如果不是空

            Uart_to_net(data,len);

            serial_back_state = OK_INPUT; //接收成功标志

            if(mes_num ++ >= 100)
            {
                ui->Write_to_device_textBrowser->clear();
                mes_num = 0;
            }

            ui->Write_to_device_textBrowser->append(data); //放进文本框

            if(log_uart)
            {
                if(ui->checkBox_save_uart_log->checkState() == Qt::Checked)
                {
                    emit log_uart->Update_log_signal(data);
                }
            }

        }
        else{
           qDebug()<<"no recv";
           serial_back_state = ER_INPUT; //空标志
        }

}
/*
 * 清除接收缓存
*/
void Main_windw::on_pushButton_3_clicked()
{
    ui->Write_to_device_textBrowser->clear();
}


void Main_windw::close_port(void)
{

    my_serial->Close();
    delete  my_serial;
    my_serial= nullptr;

    if(log_uart)
    {
        delete log_uart;
        log_uart = nullptr;
    }

    Serial_open_state = 0;

    //打开串口，按钮变亮
    ui->open_serial_pushButton->setText("打开串口");
    ui->textBrowser_megtips->setText("串口已经关闭");
    ui->open_serial_pushButton->setIcon(QIcon(":/Src/kaiguan_guan.ico"));
    ui->open_serial_pushButton->setStyleSheet("color:red");     //串口没打开，红色警告
    ui->port_number_Box->setEnabled(true);
    ui->baudrate_Box->setEnabled(true);
    ui->stop_bit_Box->setEnabled(true);
    ui->data_bit_Box->setEnabled(true);
    ui->parity_bit_Box->setEnabled(true);
}
/**
 * @brief Open_Serial_Button
 * 打开串口的按钮
 */
void Main_windw::on_open_serial_pushButton_clicked()
{
    if(ui->open_serial_pushButton->text() == "打开串口")
    {
        /*置端口名字为当前设置的值*/
        if(my_serial == nullptr)
        {
            my_serial = new SerialPort(this);
            if(log_uart == nullptr)
            {
                log_uart = new Log_save(this,"Log_uart.txt");
            }
        }

        if(my_serial->Open(ui->port_number_Box->currentText()))
        {
            //qDebug()<<"串口open成功"<<endl;

            ui->open_serial_pushButton->setStyleSheet("color:green");     //串口打开
            //设置波特率
            switch (ui->baudrate_Box->currentIndex()) { //判断当前波特率
            case 0:
                 my_serial->setBaudRate(QSerialPort::Baud9600);
                break;
            case 1:
                 my_serial->setBaudRate(QSerialPort::Baud115200);
                // qDebug()<<"设置115200成功"<<endl;
                break;
            case 2:
                 my_serial->setBaudRate(QSerialPort::Baud1200);
                break;
            case 3:
                 my_serial->setBaudRate(QSerialPort::Baud2400);
                break;
            case 4:
                 my_serial->setBaudRate(QSerialPort::Baud4800);
                break;
            case 5:
                 my_serial->setBaudRate(QSerialPort::Baud19200);
                break;
            case 6:
                my_serial->setBaudRate(QSerialPort::Baud38400);
                break;
            case 7:
                my_serial->setBaudRate(QSerialPort::Baud57600);
                break;
            default:
                break;
            }
            //设置停止位
            switch(ui->stop_bit_Box->currentIndex()){
            case 0:
                my_serial->setStopBits(QSerialPort::OneStop);
                break;
            case 1:
                my_serial->setStopBits(QSerialPort::TwoStop);
            default:
                break;
            }
            //设置数据位
            switch(ui->data_bit_Box->currentIndex()){
            case 0:
                my_serial->setDataBits(QSerialPort::Data8);
                break;
            case 1:
                my_serial->setDataBits(QSerialPort::Data5);
                break;
            case 2:
                my_serial->setDataBits(QSerialPort::Data6);
                break;
            case 3:
                my_serial->setDataBits(QSerialPort::Data7);
                break;
            default:
                break;
            }
            //设置校验位
            switch(ui->parity_bit_Box->currentIndex()){
            case 0:
                my_serial->setParity(QSerialPort::NoParity);
                break;
            case 1:
                my_serial->setParity(QSerialPort::OddParity);
                break;
            case 2:
                my_serial->setParity(QSerialPort::EvenParity);
                break;
            default:
                break;
            }
            //初始化串口默认值
            ui->open_serial_pushButton->setText("关闭串口");
            ui->textBrowser_megtips->setText("串口已经打开");
            ui->open_serial_pushButton->setIcon(QIcon(":/Src/kaiguan_kai.ico"));
            //打开串口，按钮变灰
            ui->port_number_Box->setEnabled(false);
            ui->baudrate_Box->setEnabled(false);
            ui->stop_bit_Box->setEnabled(false);
            ui->data_bit_Box->setEnabled(false);
            ui->parity_bit_Box->setEnabled(false);

            //绑定槽函数,一旦来数据，就会调用读取槽函数
            connect(my_serial,&SerialPort::ReadComplete,this,&Main_windw::data_process);

            //监测串口变动,断开自动关闭
//            connect(my_serial,&SerialPort::Serial_event_signal,this,&Main_windw::Serial_event_callback);

            Serial_open_state = 1;
        }
    }
    else
    {
        close_port();
    }

}

#endif
